Skip to content

Comments

swev-id: scikit-learn__scikit-learn-13779 - skip None estimators in sample_weight validation#35

Open
casey-brooks wants to merge 1 commit intoscikit-learn__scikit-learn-13779from
work-fix-voting-none
Open

swev-id: scikit-learn__scikit-learn-13779 - skip None estimators in sample_weight validation#35
casey-brooks wants to merge 1 commit intoscikit-learn__scikit-learn-13779from
work-fix-voting-none

Conversation

@casey-brooks
Copy link

Summary

  • skip None estimators when validating sample_weight support to match Voting* drop behaviour
  • add regression tests covering None estimators for classifier/regressor and mixed support error path

Resolves #31.

Reproduction

from sklearn.datasets import load_iris
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
import numpy as np

X, y = load_iris(return_X_y=True)
voter = VotingClassifier(
    estimators=[('lr', LogisticRegression()),
                ('rf', RandomForestClassifier())]
)
voter.fit(X, y, sample_weight=np.ones(y.shape))
voter.set_params(lr=None)
voter.fit(X, y, sample_weight=np.ones(y.shape))

Observed stack trace:

/root/.local/lib/python3.11/site-packages/sklearn/linear_model/_logistic.py:406: ConvergenceWarning: lbfgs failed to converge after 100 iteration(s) (status=1):
STOP: TOTAL NO. OF ITERATIONS REACHED LIMIT

Increase the number of iterations to improve the convergence (max_iter=100).
You might also want to scale the data as shown in:
    https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
    https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
  n_iter_i = _check_optimize_result(
Traceback (most recent call last):
  File "/root/.local/lib/python3.11/site-packages/sklearn/utils/_tags.py", line 275, in get_tags
    tags = estimator.__sklearn_tags__()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '__sklearn_tags__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 14, in <module>
  File "/root/.local/lib/python3.11/site-packages/sklearn/base.py", line 1336, in wrapper
    return fit_method(estimator, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/.local/lib/python3.11/site-packages/sklearn/ensemble/_voting.py", line 405, in fit
    return super().fit(X, transformed_y, **fit_params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/.local/lib/python3.11/site-packages/sklearn/ensemble/_voting.py", line 80, in fit
    names, clfs = self._validate_estimators()
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/.local/lib/python3.11/site-packages/sklearn/ensemble/_base.py", line 242, in _validate_estimators
    if est != "drop" and not is_estimator_type(est):
                             ^^^^^^^^^^^^^^^^^^^^^^
  File "/root/.local/lib/python3.11/site-packages/sklearn/base.py", line 1211, in is_classifier
    return get_tags(estimator).estimator_type == "classifier"
           ^^^^^^^^^^^^^^^^^^^
  File "/root/.local/lib/python3.11/site-packages/sklearn/utils/_tags.py", line 283, in get_tags
    raise AttributeError(
AttributeError: The following error was raised: 'NoneType' object has no attribute '__sklearn_tags__'. It seems that there are no classes that implement `__sklearn_tags__` in the MRO and/or all classes in the MRO call `super().__sklearn_tags__()`. Make sure to inherit from `BaseEstimator` which implements `__sklearn_tags__` (or alternatively define `__sklearn_tags__` but we don't recommend this approach). Note that `BaseEstimator` needs to be on the right side of other Mixins in the inheritance order.

Testing

  • PYTHONPATH=/workspace:${PYTHONPATH} LD_LIBRARY_PATH=/nix/store/qipd93x9gjyiygqk673rd2ssnf8y7jj0-gcc-14.3.0-lib/lib:/nix/store/gh2dd8vimringn726ndall19gbm77prj-openblas-0.3.30/lib:/nix/store/y6zrr7dfg051mz4dpjvaldy4g9cy6wmq-lapack-3/lib:/nix/store/4wdz42ns29ys6fm1xak68bnp51nxhd2s-zlib-1.3.1/lib python3 -m pytest sklearn/ensemble/tests/test_voting.py -k "none_estimator_with_sample_weight_classifier or none_estimator_with_sample_weight_regressor or sample_weight_mixed_support_with_none"
    (uses workspace sitecustomize stubs to satisfy legacy compiled dependencies)

@casey-brooks casey-brooks requested a review from a team December 26, 2025 02:22
@casey-brooks
Copy link
Author

Tests:

  • ============================= test session starts ==============================
    platform linux -- Python 3.11.14, pytest-9.0.2, pluggy-1.6.0
    rootdir: /workspace/scikit-learn
    configfile: setup.cfg
    collected 21 items / 18 deselected / 3 selected

sklearn/ensemble/tests/test_voting.py ... [100%]

================= 3 passed, 18 deselected, 3 warnings in 0.28s ================= (3 passed, 18 deselected; uses workspace sitecustomize stubs to satisfy legacy compiled deps)

Lint:

  • (no issues)

Copy link

@noa-lucent noa-lucent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skip None estimators before validating sample_weight support so Voting* drop semantics work again. Added classifier/regressor regression tests and the mixed-support guard all look good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants